<?php
namespace app\controller;

use app\BaseController;
use app\controller\model\Tables;
use liliuwei\think\Auth;
use think\facade\Session;
use think\facade\Db;
class ApiService extends BaseController
{
    protected $getpath="",$token,$nowTime,$model,$tables,$service,$gas,$order;
    protected $gobaluser="";
	protected $errStr=[0=>'参数错误',1=>'油号错误',2=>'预收单失败',3=>'订单号错误',4=>'订单状态错误',5=>'余额不足',6=>'确认失败',7=>'无操作类型',8=>'油站ID错误',9=>'无油号权限',10=>'内部错误',11=>'token错误',12=>'用户名错误',13=>'时间戳错误',14=>'签名错误',15=>'扣费失败',16=>'取消订单失败',17=>'收单失败:12',18=>'指定油站过多'];
    public function __construct(){
	    $this->getPath = strtolower(request()->controller()) . "/" . strtolower(request()->action());
	    $this->nowTime = date("Y-m-d H:i:s");
	    $this->tables = new Tables();
	   // $this->model = new model\Api();
		if($this->getPath=='apiservice/gettoken'){
			$this->checkSign();
		}else{
			$this->checkToken();
		}
    }
	public function orderInfo(){
		$service_no = request()->param("service_no");
		$order = DB::name($this->tables->serviceOrder)->alias("a")->field("a.*,b.name,b.gasID,b.address,b.province,b.city,b.country")->leftJoin($this->tables->gas." b","a.gasID=b.id")->where("a.service_no",$service_no)->where("a.serviceID",$this->service['id'])->find();
		if(!$order)echojson([],403,$this->errStr[3]);
		unset($order['id']);
		unset($order['serviceID']);
		unset($order['supplierID']);
		unset($order['supplier_no']);
		if($order['reOrder']==0){
			unset($order['reTime']);unset($order['reConfirmTime']);unset($order['reOrder']);unset($order['reContent']);
		}
		echojson($order);
	}
	public function getMyInfo(){
		echojson([
			'title'=>$this->service['title'],
			'contacts'=>$this->service['contacts'],
			'mobile'=>$this->service['mobile'],
			'amount'=>$this->service['amount'],
			'status'=>$this->service['status'],
			'getTokenTime'=>$this->service['getTokenTime'],
		]);
	}
	public function mkOrder(){
		$gasID = request()->param("gasID");
		$oil_gun = request()->param("oil_gun")*1;
		$oil_no = request()->param("oil_no");
		$amount = request()->param("amount")*1;
		$userInfo = request()->param("userInfo");
	    $log = new \app\Log("tuanyou/mk_order");
		if(strlen($gasID)<=0 || $oil_gun<1 || strlen($oil_no)<=0 || $amount<=0) echojson([],400,$this->errStr[0]);
		$this->getGas($gasID);


		if($this->gas['fromID']==2){
			$model = new \app\controller\model\Supplier(2);
			$model->getGases($this->gas['gasID']);
		}

		$addArr=[
			'supplierID'=>$this->gas['fromID'],
			'service_no'=>getOrderNo(),
			'serviceID'=>$this->service['id'],
			'gasID'=>$this->gas['id'],
			'oil_no'=>$oil_no,
			'oil_gun'=>$oil_gun,
			'amount'=>$amount,
			'userInfo'=>$userInfo,
			'addTime'=>nowTime()
		];
		$pricesArr = $this->getGasPrice($this->gas['id'],$oil_no,$this->service['inOilNo'],$this->gas['servicePrice']);
		if(!$pricesArr){
		    $log->write([
                "request" => request()->param(),
                "gas" => $this->gas,
                "message" => "油号错误"
            ]);
		    echojson([],401,$this->errStr[1]);
		}
		$reArr=$this->amountCalc($amount,$pricesArr[0]);
		$addArr = array_merge($addArr,$reArr);
		//怎么判断下重复提交问题  用户手机号是不现实的 很多用户加油不喜欢获取手机号
		$add = DB::name($this->tables->serviceOrder)->insertGetId($addArr);
		if(!$add){
		    $log->write([
                "request" => request()->param(),
                "type" => "error",
                "message" => "内部错误"
            ]);
		    echojson([],402,$this->errStr[2]);
		}
		//预收单
        $this->getMyOrder($addArr['service_no']);
        $supplierModel = new \app\controller\model\Supplier($this->order['supplierID']);
        $supplier_no = $supplierModel->mkOrder($this->order);
        if ($supplier_no !== true) {
           $log->write([
                "request" => request()->param(),
                "message" => "预收单失败"
            ]);
            echojson([], 403, $this->errStr[17]);
        }
		echojson(['service_no'=>$addArr['service_no']]);
	}
	public function cancelOrder(){
		$this->confirmOrder();
	}
	public function confirmOrder(){
		//确认之前提交到供应商 预收单和确认订单 然后在给服务商下发成功信息 然后再扣费
		$service_no = request()->param("service_no");
		$type = request()->param("type");
		$log = new \app\Log("tuanyou/confirm");
		lock();
		$this->getMyOrder($service_no,true);
		if(!$this->order)echojson([],403,$this->errStr[3]);
		$supplierModel = new \app\controller\model\Supplier($this->order['supplierID']);
		if($type=='confirm'){
			if($this->order['status']!=0)echojson([],404,$this->errStr[4]);//订单状态错误
			//确认订单
			//判断服务商金额 重新锁定服务商
			$this->checkToken(true);
			if($this->service['amount'] < $this->order['realPrice'])echojson([],405,$this->errStr[5]);//余额不足
			//先上传到上游供应商
// 			$supplier_no = $supplierModel->mkOrder($this->order);
// 			if($supplier_no===true){
// 				$this->getMyOrder($service_no);
				$supplierModel->confirmOrder($this->order);//不用判断 确认失败会直接发回错误
// 			}else{
// 			    file_put_contents($dir . "/" . date("H") . ".log", json_encode([
//                         "time" => date("Y-m-d H:i:s"),
//                         "request" => request()->param(),
//                         "return" => $supplier_no,
//                         "type" => "error",
//                         "message" => "收单失败"
//                     ],320) . "\r\n", FILE_APPEND);
// 				echojson([],417,$this->errStr[17]);//收单失败:12
// 			}
			//上游供应商确认订单
			//确认结束
			$setOrder = DB::name($this->tables->serviceOrder)->where("id",$this->order['id'])->update(['status'=>1]);
			if(!$setOrder){
			   $log->write([
                    "request" => request()->param(),
                    "return" => $this->order,
                    "message" => "订单确认失败"
                ]);
			    echojson([],406,$this->errStr[6]);//确认失败
			}
			//本地确认成功 扣费
			$this->addAmount(-$this->order['realPrice']);
			echojson();
		}
		if($type=='cancel2'){//这里是直接取消 弃用
			echojson([],1,'废弃接口');
			//取消已确认的订单
			if($this->order['status']!=1)echojson([],404,$this->errStr[4]);//订单状态错误
			//上游供应商取消订单
			$supplierModel->cancelOrder($this->order['supplier_no']);
			//上游取消成功
			$setOrder = DB::name($this->tables->serviceOrder)->where("id",$this->order['id'])->update(['status'=>-1,'cancelTime'=>nowTime()]);
			if(!$setOrder)echojson([],416,$this->errStr[16]);//取消订单失败
			//本地取消成功 扣费
			$this->addAmount($this->order['realPrice']);
			echojson();
		}
		if($type=='cancel'){
			//申请取消订单
			if($this->order['status']!=1 && $this->order['status']!=0)echojson([],404,$this->errStr[4]);//订单状态错误
			$setOrder = DB::name($this->tables->serviceOrder)->where("id",$this->order['id'])->update(['reOrder'=>1,'reTime'=>nowTime()]);
			if(!$setOrder){
			   $log->write([
                    "request" => request()->param(),
                    "return" => $this->order,
                    "message" => "订单取消失败"
                ]);
			    echojson([],416,$this->errStr[16]);//取消订单失败
			}
			echojson();
		}
		echojson([],407,$this->errStr[7]);
	}
	public function calcMyPrice(){
		$gasID = request()->param("gasID");
		$amount = request()->param("amount");
		$oil_no = request()->param("oil_no");
		$this->getGas($gasID);
		if(!$this->gas)echojson([],408,$this->errStr[8]);
		$pricesArr = $this->getGasPrice($this->gas['id'],$oil_no,$this->service['inOilNo'],$this->gas['servicePrice']);
		if($pricesArr){
			$reArr=$this->amountCalc($amount,$pricesArr[0]);
			$reArr['amount']=$amount;
			$reArr['price_gun']=$pricesArr[0]['price_gun'];
			$reArr['price_yfq']=$pricesArr[0]['price_yfq'];
			echojson($reArr);
		}
		echojson([],409,$this->errStr[9]);
	}
	public function getList(){
		$gasIDS = request()->param("gasIDS");
		$where="status > 0";
		if($gasIDS!=''){
			$gasIDS = str_replace("，",",",$gasIDS);
			$gasIDS = explode(",",$gasIDS);
			if(count($gasIDS)>50)echojson([],418,$this->errStr[18]);
			$gasIDS = array_map(function($id) {
				return "'" . $id . "'";
			}, $gasIDS);
			$result = preg_replace('/[^a-zA-Z0-9,\']/u', '', implode(",",$gasIDS));//过滤字符串 要不然会有sql注入漏洞
			$where .= " and gasID in (".$result.")";
		}
		//读取看看是否有指定gas
		$serviceGasInTips = $this->service['inGasTips'];
		if($serviceGasInTips!='' && $serviceGasInTips!=null){
			$where .= " and id in (".rTipsToIds2($serviceGasInTips).")";
		}
		$res = getpagedata($this->tables->gas,"",true,$where);
		//读取价格
		$count=$res[1];
		$res = $res[0]->all();
		foreach ($res as &$v){
			$v['price'] = $this->getGasPrice($v['id'],'',$this->service['inOilNo'],$v['servicePrice']);
			unset($v['id']);
			unset($v['subPrice']);
			unset($v['localStatus']);
			unset($v['fromID']);
			unset($v['upNumber']);
			unset($v['addTime']);
		}
		pagejson($res,0,'',$count);
	}
    public function getToken(){
		$up = DB::name($this->tables->service)->save($this->service);
		if(!$up)echojson([],410,$this->errStr[10]);
		echojson(['token'=>$this->service['token'],'lastGetTime'=>$this->service['getTokenTime']]);
    }
	protected function addAmount($amount=0){
		if($amount==0)echojson([],415,$this->errStr[15]);
		$endAmount = bcadd($this->service['amount'],$amount,2);
		$addArr = [
			'gasID'=>$this->order['gasID'],
			'supplierID'=>$this->order['supplierID'],
			'serviceID'=>$this->service['id'],
			'orderID'=>$this->order['id'],
			'startAmount'=>$this->service['amount'],
			'endAmount'=>$endAmount,
			'amount'=>$amount,
			'status'=>1,
			'addTime'=>nowTime(),
		];
		$add = DB::name($this->tables->serviceAmount)->insert($addArr);
		$add = DB::name($this->tables->service)->where("id",$this->service['id'])->update(['amount'=>$endAmount]);
		if(!$add)echojson([],415,$this->errStr[15]);
	}
	protected function getMyOrder($orderID='',$lock=false){
		$this->order = DB::name($this->tables->serviceOrder)->where("service_no",$orderID)->where("serviceID",$this->service['id']);
		if($lock)$this->order = $this->order->lock(true);
		$this->order = $this->order->find();
	}
	protected function checkToken($lock=false){
		$token = request()->param("token");
		$this->service = DB::name($this->tables->service);
		if($lock)$this->service = $this->service->lock(true);
		$this->service = $this->service->where("token",$token)->find();
		if($this->service['status']==-1)echojson([],480,$this->service['content']);
		if(!$this->service)echojson([],411,$this->errStr[11]);
	}
	protected function amountCalc($amount=0,$priceArr=[]){
		$price_yfq = $priceArr['price_yfq'];
		$price_gun = $priceArr['price_gun'];
		$litre = round($amount/$price_gun,4);
		$realPrice = round($litre*$price_yfq,2);
		return ['litre'=>$litre,'realPrice'=>$realPrice,'salePrice'=>bcsub($amount,$realPrice,2),'price_yfq'=>$price_yfq,'price_gun'=>$price_gun];
	}
	protected function checkSign(){
		$username = request()->param("username");
		$time = request()->param("time");
		$sign = request()->param("sign");
		$this->service = DB::name($this->tables->service)->where("username",$username)->find();
		if(!$this->service)echojson([],412,$this->errStr[12]);
		if($time<$this->service['getTokenTime'])echojson([],413,$this->errStr[13]);
		$temSign = md5($username.$time.$this->service['key']);
		if($temSign!=$sign)echojson([],414,$this->errStr[14]);
		DB::name($this->tables->serviceToken)->insert(['serviceID'=>$this->service['id'],'token'=>$this->service['token'],'addTime'=>nowTime(),'serviceName'=>$this->service['title']]);
		$this->service['token']=md5($temSign."isiOs8**1");
		$this->service['getTokenTime']=time();
	}
	protected function getGas($gasID=0){
		$this->gas = DB::name($this->tables->gas);
		if(is_string($gasID)){
			$this->gas = $this->gas->where("gasID",$gasID)->where("status",1)->find();
		}else{
			$this->gas = $this->gas->where("id",$gasID)->where("status",1)->find();
		}
		if(!$this->gas){
			echojson([],420,'油站未营业');
		}
	}
	protected function getGasPrice($gasID=0,$oil_no='',$inIDS='',$servicePrice=null){//$servicePrice特殊一对一指定了的
		$gasPrice = DB::name($this->tables->gasPrice)->where("gasID",$gasID);
		if($oil_no!=''){
			$gasPrice = $gasPrice->where("oil_no",$oil_no);
		}
		else if($inIDS!='' && $inIDS!=null){
			$gasPrice = $gasPrice->whereIn("oil_no",$inIDS);
		}
// 		@file_put_contents("./sql.log",$gasPrice->buildSql()."\r\n",8);
		$gasPrice = $gasPrice->select();
		$gasPrice = $gasPrice->all();
		$gasPrice = $this->getServicePrice($gasPrice,$servicePrice,$gasID);
		return $gasPrice;
	}
	protected function getServicePrice($gasPriceArr=[],$servicePrice=null,$gasID=0){
		if($servicePrice!=null && $servicePrice!=''){
			$servicePrice = explode(",",$servicePrice);
			if(is_array($servicePrice) && count($servicePrice)>0 && in_array($this->service['id'],$servicePrice)){
				$servicePriceRe = DB::name($this->tables->gasServicePrice)->where("gasID",$gasID)->where("serviceID",$this->service['id'])->find();
				if($servicePriceRe)$subPercent=$servicePriceRe['percent'];
			}
		}
		if(!isset($subPercent) || $subPercent<=0){
			$subPercent = $this->service['subPercent'];
			$subPrice = $this->service['subPrice'];
			if($subPrice<=0 && $subPercent<=0)$subPercent = r_rule2(276)['rule'];
			$subType = "percent";
			if($subPrice>0)$subType = "price";
			if($subPrice>0)$subPercent = $subPrice;
		}else{
			$subType = "percent";
		}

		foreach ($gasPriceArr as &$v){
			$v['gun_nos']=json_decode($v['gun_nos'],true);
			$v = $this->calcPrice($subType,$v,$subPercent);
			unset($v['id']);
			unset($v['gasID']);
			unset($v['tail']);
		}
		return $gasPriceArr;
	}
	protected function calcPrice($type="percent",$priceArr=[],$percent=0){
		$cha = bcsub($priceArr['price_gun'],$priceArr['price_yfq'],4);
		
		if($type == 'percent'){
		    if($percent <= 0) return $priceArr;
            $priceArr['price_yfq'] = round($priceArr['price_yfq'] * bcdiv($percent, 100, 4),2);
// 			$cha = bcmul($cha,$percent,4);
// 			$cha = bcdiv($cha,100,4);
			@file_put_contents("./test.log",json_encode([$cha,$priceArr,$percent])."\r\n",8);
		}else{
			$cha = $percent;
			$priceArr['price_yfq'] = bcsub($priceArr['price_yfq'],$cha,2);
		}
	
		return $priceArr;
	}
}
